home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / CLOUD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.9 KB  |  244 lines

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6.  
  7. #ifndef __sgi
  8. /* Most math.h's do not define float versions of the math functions. */
  9. #define expf(x) ((float)exp((x)))
  10. #endif
  11.  
  12. static float ttrans[2];
  13. static float scale = 1.;
  14. static float transx, transy, rotx, roty;
  15. static int ox = -1, oy = -1;
  16. static int mot;
  17. #define PAN    1
  18. #define ROT    2
  19.  
  20. void
  21. pan(int x, int y) {
  22.     transx +=  (x-ox)/500.;
  23.     transy -= (y-oy)/500.;
  24.     ox = x; oy = y;
  25.     glutPostRedisplay();
  26. }
  27.  
  28. void
  29. rotate(int x, int y) {
  30.     rotx += x-ox;
  31.     if (rotx > 360.) rotx -= 360.;
  32.     else if (rotx < -360.) rotx += 360.;
  33.     roty += y-oy;
  34.     if (roty > 360.) roty -= 360.;
  35.     else if (roty < -360.) roty += 360.;
  36.     ox = x; oy = y;
  37.     glutPostRedisplay();
  38. }
  39.  
  40. void
  41. motion(int x, int y) {
  42.     if (mot == PAN) pan(x, y);
  43.     else if (mot == ROT) rotate(x,y);
  44. }
  45.  
  46. void
  47. mouse(int button, int state, int x, int y) {
  48.     if(state == GLUT_DOWN) {
  49.     switch(button) {
  50.     case GLUT_LEFT_BUTTON:
  51.         mot = PAN;
  52.         motion(ox = x, oy = y);
  53.         break;
  54.     case GLUT_RIGHT_BUTTON:
  55.         mot = ROT;
  56.         motion(ox = x, oy = y);
  57.         break;
  58.     case GLUT_MIDDLE_BUTTON:
  59.         break;
  60.     }
  61.     } else if (state == GLUT_UP) {
  62.     mot = 0;
  63.     }
  64. }
  65.  
  66. #if NATE
  67. void 
  68. wire(void) {
  69.     static int w;
  70.     if (w ^= 1)
  71.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  72.     else
  73.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  74. }
  75. #endif
  76.  
  77. void up(void) { scale += .1; }
  78. void down(void) { scale -= .1; }
  79.  
  80. void
  81. animate(void) {
  82.     ttrans[0] += .01;
  83.     if (ttrans[0] == 1.0) ttrans[0] = 0;
  84.     ttrans[1] += .005;
  85.     if (ttrans[1] == 1.0) ttrans[1] = 0;
  86.     glutPostRedisplay();
  87. }
  88.  
  89. void help(void) {
  90.     printf("Usage: cloud [image]\n");
  91.     printf("'h'            - help\n");
  92. #if NATE
  93.     printf("'w'            - toggle wireframe\n");
  94. #endif
  95.     printf("'UP'           - scale up\n");
  96.     printf("'DOWN'         - scale down\n");
  97.     printf("left mouse     - pan\n");
  98.     printf("right mouse    - rotate\n");
  99. }
  100.  
  101. void init(char *filename) {
  102.     GLfloat cloud_color[4] = { 1., 1., 1., 0., };
  103.     GLfloat fog_color[4], fog_density = 0.05, density, far_cull;
  104.     unsigned *image;
  105.     int width, height, components;
  106.     if (filename) {
  107.     image = read_texture(filename, &width, &height, &components);
  108.     if (image == NULL) {
  109.         fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  110.             filename);
  111.         exit(EXIT_FAILURE);
  112.     } else {
  113.         printf("%d x %d image loaded\n", width, height);
  114.     }
  115.     if (components != 1) {
  116.         printf("must be a bw image\n");
  117.         exit(EXIT_FAILURE);
  118.     }
  119.     } else {
  120.     int i, j;
  121.     unsigned char *img;
  122.     components = 4; width = height = 512;
  123.     image = (unsigned *) malloc(width*height*sizeof(unsigned));
  124.     img = (unsigned char *)image;
  125.     for (j = 0; j < height; j++)
  126.         for (i = 0; i < width; i++) {
  127.         int w2 = width/2, h2 = height/2;
  128.         if (i & 32)
  129.             img[4*(i+j*width)+0] = 0xff;
  130.         else
  131.             img[4*(i+j*width)+1] = 0xff;
  132.         if (j&32)
  133.             img[4*(i+j*width)+2] = 0xff;
  134.         if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 &&
  135.             (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff;
  136.         }
  137.  
  138.     }
  139.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  140.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
  141.     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cloud_color);
  142.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  143.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  144.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  145.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  146.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  147.                  height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  148.                  image);
  149.     glEnable(GL_TEXTURE_2D);
  150.     glMatrixMode(GL_PROJECTION);
  151.     glLoadIdentity();
  152.     gluPerspective(50.,1.,.1,far_cull = 10.);
  153.     glMatrixMode(GL_MODELVIEW);
  154.     glLoadIdentity();
  155.     glTranslatef(0.,0.,-5.5);
  156.  
  157.     density = 1.- expf(-5.5 * fog_density * fog_density *
  158.                   far_cull * far_cull);
  159.  
  160. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  161. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  162.     density = MAX(MIN(density, 1.), 0.);
  163.  
  164.     fog_color[0] = .23 + density *.57;
  165.     fog_color[1] = .35 + density *.45;
  166.     fog_color[2] = .78 + density *.22;
  167.  
  168.     glClearColor(fog_color[0], fog_color[1], fog_color[2], 1.f);
  169.  
  170.     glFogi(GL_FOG_MODE, GL_EXP2);
  171.     glFogf(GL_FOG_DENSITY, fog_density);
  172.     glFogfv(GL_FOG_COLOR, fog_color);
  173.     if (fog_density > 0)
  174.     glEnable(GL_FOG);
  175. }
  176.  
  177. void display(void) {
  178.     glClear(GL_COLOR_BUFFER_BIT);
  179.     glPushMatrix();
  180.     glTranslatef(transx, transy, 0.f);
  181.     glRotatef(rotx, 0., 1., 0.);
  182.     glRotatef(roty, 1., 0., 0.);
  183.     glScalef(scale,scale,1.);
  184.     glScalef(10,1,10);
  185.     glColor3f(.19, .25, .70);
  186.     glMatrixMode(GL_TEXTURE);
  187.     glPushMatrix();
  188.     glTranslatef(ttrans[0], ttrans[1], 0.);
  189.     glBegin(GL_QUADS);
  190.     glTexCoord2f(0, 0); glVertex3f(-1., 1., -1.);
  191.     glTexCoord2f(0, 5); glVertex3f(-1., 1.,  1.);
  192.     glTexCoord2f(5, 5); glVertex3f( 1., 1.,  1.);
  193.     glTexCoord2f(5, 0); glVertex3f( 1., 1., -1.);
  194.     glEnd();
  195.     glPopMatrix();
  196.     glMatrixMode(GL_MODELVIEW);
  197.     glPopMatrix();
  198.     glutSwapBuffers();
  199. }
  200.  
  201. void reshape(int w, int h) {
  202.     glViewport(0, 0, w, h);
  203. }
  204.  
  205. /*ARGSUSED1*/
  206. void
  207. key(unsigned char key, int x, int y) {
  208.     switch(key) {
  209. #if NATE
  210.     case 'w': wire(); break;
  211. #endif
  212.     case 'h': help(); break;
  213.     case '\033': exit(EXIT_SUCCESS); break;
  214.     default: break;
  215.     }
  216.     glutPostRedisplay();
  217. }
  218.  
  219. /*ARGSUSED1*/
  220. void
  221. special(int key, int x, int y) {
  222.     switch(key) {
  223.     case GLUT_KEY_UP:    up(); break;
  224.     case GLUT_KEY_DOWN:    down(); break;
  225.     }
  226. }
  227.  
  228. int main(int argc, char** argv) {
  229.     glutInitWindowSize(512, 512);
  230.     glutInit(&argc, argv);
  231.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
  232.     (void)glutCreateWindow(argv[0]);
  233.     init(argc == 1 ? "data/clouds.bw" : argv[1]);
  234.     glutDisplayFunc(display);
  235.     glutKeyboardFunc(key);
  236.     glutSpecialFunc(special);
  237.     glutReshapeFunc(reshape);
  238.     glutMouseFunc(mouse);
  239.     glutMotionFunc(motion);
  240.     glutIdleFunc(animate);
  241.     glutMainLoop();
  242.     return 0;
  243. }
  244.